package hong.jun.funure;


import org.junit.Test;

import java.sql.SQLOutput;
import java.util.Random;
import java.util.concurrent.*;


/**
 * 说明:
 * Created on 2023/10/27 10:40
 *
 * @author yanghongjun <1737619387@qq.com>
 */
public class TeaTest {

    //烧水泡茶
    @Test
    public void tea() throws ExecutionException, InterruptedException {
        // 创建任务T2的FutureTask
        FutureTask<String> ft2 = new FutureTask<>(new T2Task());
        // 创建任务T1的FutureTask
        FutureTask<String> ft1 = new FutureTask<>(new T1Task(ft2));
        // 线程T1执行任务ft1
        Thread t1 = new Thread(ft1);
        t1.start();
        // 线程T2执行任务ft2
        Thread t2 = new Thread(ft2);
        t2.start();
        // 等待线程T1执行结果
        System.out.println(ft1.get());
    }


    // T1Task需要执行的任务：
    // 洗水壶、烧开水、泡茶
    static class T1Task implements Callable<String> {
        FutureTask<String> ft2;

        // T1任务需要T2任务的FutureTask
        T1Task(FutureTask<String> ft2) {
            this.ft2 = ft2;
        }

        @Override
        public String call() throws Exception {
            System.out.println("T1:洗水壶...");
            TimeUnit.SECONDS.sleep(1);

            System.out.println("T1:烧开水...");
            TimeUnit.SECONDS.sleep(15);
            // 获取T2线程的茶叶
            String tf = ft2.get();
            System.out.println("T1:拿到茶叶:" + tf);

            System.out.println("T1:泡茶...");
            return "上茶:" + tf;
        }
    }

    // T2Task需要执行的任务:
    // 洗茶壶、洗茶杯、拿茶叶
    static class T2Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("T2:洗茶壶...");
            TimeUnit.SECONDS.sleep(1);

            System.out.println("T2:洗茶杯...");
            TimeUnit.SECONDS.sleep(2);

            System.out.println("T2:拿茶叶...");
            TimeUnit.SECONDS.sleep(1);
            return "龙井";
        }
    }


    //查询价格
    @Test
    public void findPrice() throws ExecutionException, InterruptedException {
        //FutureTask<Integer> f1 = new FutureTask<>(() -> random());
        FutureTask<Integer> f1 = new FutureTask<>(this::random);
        FutureTask<Integer> f2 = new FutureTask<>(this::random);
        FutureTask<Integer> f3 = new FutureTask<>(this::random);
        Thread thread1 = new Thread(f1);
        thread1.start();
        Thread thread2 = new Thread(f2);
        thread2.start();
        Thread thread3 = new Thread(f3);
        thread3.start();
        System.out.println("获取价格f1：" + f1.get());
        System.out.println("获取价格f2：" + f2.get());
        System.out.println("获取价格f3：" + f3.get());
    }

    public int random() {
        Random random = new Random();
        return random.nextInt(10);
    }


    //CompletableFuture烧水泡茶
    @Test
    public void tea1() throws ExecutionException, InterruptedException {
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {
            try {
                System.out.println("T1:洗水壶...");
                Thread.sleep(1000);
                System.out.println("T1:烧开水...");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        });
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
            try {
                System.out.println("T2:洗茶壶...");
                Thread.sleep(2000);
                System.out.println("T2:洗茶杯...");
                Thread.sleep(2000);
                System.out.println("T2:拿茶叶...");
                Thread.sleep(1000);
                return "龙井";
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        CompletableFuture<String> f3 = f1.thenCombine(f2, (__, tf) -> {
            System.out.println("T1:拿到茶叶:" + tf);
            System.out.println("T1:泡茶...");
            return "上茶:" + tf;
        });
        f3.join();
        System.out.println(f3.get());
    }
}
